package com.ruleengine.db.config;

import java.time.LocalDateTime;

import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;

/**
 * @author lianghanwei on 2024/3/16
 */
@Configuration
@MapperScan("com.ruleengine.db.mapper")
public class MyBatisPlusConfig {

    private static final String CREATE_TIME_FIELD_NAME = "createTime";
    private static final String UPDATE_TIME_FIELD_NAME = "updateTime";

    /**
     * 自动填充 CREATE_TIME_FIELD_NAME、UPDATE_TIME_FIELD_NAME
     */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MetaObjectHandler() {

            @Override
            public void insertFill(MetaObject metaObject) {
                if (metaObject.hasSetter(CREATE_TIME_FIELD_NAME)) {
                    this.strictInsertFill(metaObject, CREATE_TIME_FIELD_NAME, LocalDateTime::now, LocalDateTime.class);
                }

                if (metaObject.hasSetter(UPDATE_TIME_FIELD_NAME)) {
                    this.strictInsertFill(metaObject, UPDATE_TIME_FIELD_NAME, LocalDateTime::now, LocalDateTime.class);
                }
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                boolean hasUpdateTime = metaObject.hasSetter(UPDATE_TIME_FIELD_NAME);
                Object customUpdateTime = getFieldValByName(UPDATE_TIME_FIELD_NAME, metaObject);

                // 如果有自定义的更新时间，就不自动填充了
                if (hasUpdateTime && customUpdateTime == null) {
                    this.strictUpdateFill(metaObject, UPDATE_TIME_FIELD_NAME, LocalDateTime::now, LocalDateTime.class);
                }
            }

        };
    }

    /**
     * 乐观锁，处理 @Version 标记的字段
     * https://baomidou.com/pages/0d93c0/#_1-%E9%85%8D%E7%BD%AE%E6%8F%92%E4%BB%B6
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}
